﻿using CLVisionTrace;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static CLVisionLightControlTS.AbstractIODevice;
using static CLVisionLightControlTS.AbstractLightDevice;

namespace CLVisionLightControlTS
{

#if _WIN32
    using ControllerHandle = Int32;
    using ControllerHandleType = Int32;
#else
    using ControllerHandle = Int64;
    using ControllerHandleType = Int64;
#endif
    public class SoftTriggerControl
    {
        //实例化LogTrace对象（设成静态）
        private static LogTrace trace = new LogTrace();

        //准备日志保存路径
        private static MethodBase currentMethod = MethodBase.GetCurrentMethod();
        private static string namespaceName = currentMethod.DeclaringType.Namespace;
        private static string basePath = "D://OpconData//Trace";
        //记录日志全局开关
        private static bool g_LogEnable = true;
        public static bool G_LogEnable { get => g_LogEnable; set => g_LogEnable = value; }

        private static AbstractLightDevice LightDevice = null;
        private static ConcurrentDictionary<string, uint> IP_DataSocket = new ConcurrentDictionary<string, uint>();

        /// <summary>
        /// 初始化，连接光源
        /// </summary>
        /// <param name="lightBrand"></param>
        /// <param name="IP"></param>
        /// <param name="iPort"></param>
        /// <param name="DataSocket"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool Init(LightBrand lightBrand, string IP, int iPort, out uint DataSocket, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "Init successfully!";
            Occurred = false;
            try
            {
                //// 订阅进程退出事件
                //AppDomain.CurrentDomain.ProcessExit += (s, e) =>
                //{
                //    // 这里的代码会在进程退出时执行
                //    List<uint> dataSocket = new List<uint>();
                //    for (int i = 0; i < IP_DataSocket.Count; i++)
                //    {
                //        int k = i;
                //        dataSocket.Add(IP_DataSocket.ElementAt(k).Value);
                //    }
                //    for (int j = 0; j < dataSocket.Count; j++)
                //    {
                //        int m = j;
                //        DeInit(dataSocket[m], out _, out _, out _);
                //    }
                //    MessageBox.Show("OKOKOKOK");
                //};
                AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
                //设置日志路径和开关
                trace.SetLogPath(basePath + "//" + namespaceName);
                trace.G_LogEnable = g_LogEnable;
                if (!IP_DataSocket.ContainsKey(IP))
                {
                    if (lightBrand == LightBrand.RS)
                    {
                        LightDevice = new RSLight();
                    }
                    else if (lightBrand == LightBrand.CST)
                    {
                        LightDevice = new CSTLight();
                    }
                    LightDevice.Init(IP, iPort, out DataSocket, out ErrorCode, out ErrorText, out Occurred);
                    if (ErrorCode == 0)
                    {
                        IP_DataSocket.TryAdd(IP, DataSocket);
                    }
                    else
                    {
                        trace.Error(ErrorText);
                        return false;
                    }
                }
                else
                {
                    IP_DataSocket.TryGetValue(IP, out uint value);
                    DataSocket = value;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"Init failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                DataSocket = 0;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 释放，断开光源
        /// </summary>
        /// <param name="DataSocket"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool DeInit(uint DataSocket, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "DeInit successfully!";
            Occurred = false;
            try
            {
                if (LightDevice != null)
                {
                    LightDevice.DeInit(DataSocket, out ErrorCode, out ErrorText, out Occurred);
                    if (ErrorCode != 0)
                    {
                        trace.Error(ErrorText);
                        return false;
                    }
                    List<int> index = new List<int>();
                    for (int i = 0; i < IP_DataSocket.Count; i++)
                    {
                        int k = i;
                        if (IP_DataSocket.ElementAt(k).Value == DataSocket)
                        {
                            index.Add(k);
                        }
                    }
                    for (int j = 0; j < index.Count; j++)
                    {
                        int k = j;
                        string ip = IP_DataSocket.ElementAt(index[k]).Key;
                        IP_DataSocket.TryRemove(ip, out uint datasocket);
                    }
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"DeInit failed,LightDevice object is null!";
                    Occurred = true;
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"DeInit Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 设置触发模式
        /// </summary>
        /// <param name="DataSocket"></param>
        /// <param name="Mode"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool TriggerMode(uint DataSocket, int Mode, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "TriggerMode successfully!";
            Occurred = false;
            try
            {
                if (LightDevice != null)
                {
                    LightDevice.TriggerMode(DataSocket, Mode, out ErrorCode, out ErrorText, out Occurred);
                    if (ErrorCode != 0)
                    {
                        trace.Error(ErrorText);
                        return false;
                    }
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"TriggerMode failed,LightDevice object is null!";
                    Occurred = true;
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"TriggerMode failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 打开光源
        /// </summary>
        /// <param name="DataSocket"></param>
        /// <param name="LightData"></param>
        /// <param name="LightTime"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool OpenLight(uint DataSocket, int[] LightData, int LightTime, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "OpenLight successfully!";
            Occurred = false;
            try
            {
                if (LightDevice != null)
                {
                    LightDevice.OpenLight(DataSocket, LightData, LightTime, out ErrorCode, out ErrorText, out Occurred);
                    if (ErrorCode != 0)
                    {
                        trace.Error(ErrorText);
                        return false;
                    }
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"OpenLight failed,LightDevice object is null!";
                    Occurred = true;
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"OpenLight failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 关闭光源
        /// </summary>
        /// <param name="DataSocket"></param>
        /// <param name="LightTime"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool CloseLight(uint DataSocket, int LightTime, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "CloseLight successfully!";
            Occurred = false;
            try
            {
                if (LightDevice != null)
                {
                    LightDevice.CloseLight(DataSocket, LightTime, out ErrorCode, out ErrorText, out Occurred);
                    if (ErrorCode != 0)
                    {
                        trace.Error(ErrorText);
                        return false;
                    }
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"CloseLight failed,LightDevice object is null!";
                    Occurred = true;
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"CloseLight failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 在线/离线模式
        /// </summary>
        /// <param name="DataSocket"></param>
        /// <param name="offlineOrOnline"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool OfflineOrOnline(uint DataSocket, bool offlineOrOnline, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "OfflineOrOnline successfully!";
            Occurred = false;
            try
            {
                if (LightDevice != null)
                {
                    LightDevice.OfflineOrOnline(DataSocket, offlineOrOnline, out ErrorCode, out ErrorText, out Occurred);
                    if (ErrorCode != 0)
                    {
                        trace.Error(ErrorText);
                        return false;
                    }
                }
                else
                {
                    ErrorCode = -1;
                    ErrorText = $"OfflineOrOnline failed,LightDevice object is null!";
                    Occurred = true;
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"OfflineOrOnline failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        private SoftTriggerControl()
        {
            // 订阅进程退出事件
            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        }

        private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            // 这里的代码会在进程退出时执行
            List<uint> dataSocket = new List<uint>();
            for (int i = 0; i < IP_DataSocket.Count; i++)
            {
                int k = i;
                dataSocket.Add(IP_DataSocket.ElementAt(k).Value);
            }
            for (int j = 0;j < dataSocket.Count; j++)
            {
                int m = j;
                DeInit(dataSocket[m], out int ErrorCode, out string ErrorText, out bool Occurred);
            }
        }
    }
}
